﻿package com.firstpixel.multiuser.soccergame
{      
    import flash.display.*;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.*;
	
   	import caurina.transitions.Tweener;
	
	import Box2D.Dynamics.b2DebugDraw;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2World;
	import Box2D.Collision.*;
 	import Box2D.Collision.Shapes.*;
 	import Box2D.Dynamics.Joints.*;
 	import Box2D.Dynamics.Contacts.*;
 	import Box2D.Common.*;
 	import Box2D.Common.Math.*;	
	
	//Papervision3D
	import org.papervision3d.events.FileLoadEvent;
	import org.papervision3d.cameras.SpringCamera3D;
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.cameras.DebugCamera3D;
	import org.papervision3d.core.proto.MaterialObject3D;
	import org.papervision3d.core.render.command.*;
	import org.papervision3d.core.clipping.FrustumClipping;
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.objects.*;
	import org.papervision3d.scenes.*;
	import org.papervision3d.objects.parsers.*;
	import org.papervision3d.objects.primitives.*;
	import org.papervision3d.objects.special.*;
	import org.papervision3d.view.*;
	import org.papervision3d.view.layer.*;
	import org.papervision3d.view.layer.util.*;
	import org.papervision3d.materials.*;
	import org.papervision3d.materials.shadematerials.*;
	import org.papervision3d.materials.utils.*;
	import org.papervision3d.materials.shaders.*;
	import org.papervision3d.materials.special.*;
	import org.papervision3d.render.*;
	import org.papervision3d.lights.PointLight3D;
	//fog
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.core.render.filter.FogFilter;
	import org.papervision3d.materials.special.FogMaterial;
     
	 	
	import com.firstpixel.utils.*;
	import com.firstpixel.physics.*;
	import com.firstpixel.world3d.*;
	import com.firstpixel.multiuser.soccergame.*
	  
	  
     public class BasicView3DGame extends BasicView {   
 		
		private var springCamera:SpringCamera3D;
       	private var mt:Load3DMaterial
	   private var infinityGround:Plane;
		private var ground1 , ground2 , ground3 , ground4 :Plane;
		private var sky:Cylinder;
		private var ball:DisplayObject;
		private var selectedCamera:Number = 0;
		private var changingCamera:Boolean = false;
		private var DAETriangles:Array = new Array();
		private var BoundingCube:Cube;
		private var sphere:Sphere;
		private var debugContainer:Sprite = new Sprite();
		var mapIsLoaded = false;
		var bodies:Array;
		//Physics
		private var m_world:b2World;
		private var m_iterations:int = 20;
		private var m_timeStep:Number = 1.0/30.0;
		
		private var dynamic3DObjList:Array = new Array();
		
		
	   public function BasicView3DGame()
		{
			   init3D()
			
			//super();
		}  
		//START PHYSIC ENGINE
		private  function startPhysicEngine ():void{
			// Create world AABB
			var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-100.0, -100.0);
			worldAABB.upperBound.Set(100.0, 100.0);
			// Define the gravity vector
			var gravity:b2Vec2 = new b2Vec2(0.0, 0.0);
			var doSleep:Boolean = true;
			m_world = new b2World(worldAABB, gravity, doSleep); // Construct a world object
			m_world.SetContactListener(new ObjectContactListener());
			var m_physScale:uint = 30;
			var builder = new Box2DGenerator(m_world, m_physScale);
			//init with destination world and the scale constant   			
			bodies = builder.convertClipToBox2D(root["room"+_room]); //send a reference to a MovieClip with named objects in it
			physicDebug();
		}
		// set debug draw
		private function physicDebug():void{	
			var debugSprite = new Sprite();
			addChild( debugSprite );
			dbgDraw.SetSprite( debugSprite );
			dbgDraw.SetDrawScale( 60.0 );
			dbgDraw.SetFillAlpha( 0.5 );
			dbgDraw.SetLineThickness( 1.0 );
			dbgDraw.SetFlags( b2DebugDraw.e_shapeBit | b2DebugDraw.e_centerOfMassBit );
			m_world.SetDebugDraw( dbgDraw );
		}
		private function onMapsLoaded(e:Event){
			trace("LOADED")
			//loadingTxt += "MAPS Loaded :"+e.currentTarget+"\n";
			//loading_mc.loading_txt.text = loadingTxt;	
			mapIsLoaded = true;
			startRendering();
			
		}
		//*********************************************************************//
		//																	   //
		//								BUILD WORLD 						   //
		//																	   //
		//*********************************************************************//
		
		
		// Add Objects from MovieClip 2DEngine to the 3D World
		//type : tree, wall, 
		private function convertClipTo3DWorld(target:MovieClip):Array
		{	
				var i:int;
				var child:MovieClip;
				for(i=0;i<target.numChildren; i++){
					child = target.getChildAt(i) as MovieClip;
					var tempRotation:Number = child.rotation/180*Math.PI;		
					
					var hPos = child.heightPosition;
					var _w = child.w;
					var _h = child.h;
					var _segmentsW = child.segmentsW;
					var _segmentsH = child.segmentsH;
					var material = child.material!=undefined?mt[child.material]:null;		
					var tempName = child.name!=null?child.name:"";
					if(material && (material is BitmapFileMaterial)){
						material.baked = child.baked;
						material.precise = child.precise;
						material.tiled = child.tiled;
						material.maxU = child.maxU;
						material.maxV = child.maxV;
						material.doubleSided = child.doubleSided;
						material.smooth = child.smooth;
						material.interactive = child.interactive;
					}
					//trace("MATERIAL :"+material)
					
		
					//tempName.name = child.name;
						
					
					switch(String(child.name).substr(0,6)){
						case 'staCro':
							tempName = new CrossedObject( material, _w, _h );
							tempName.y = hPos;
							tempName.z = -(child.y-250)*4;
							tempName.x = (child.x-250)*4;
							tempName.useClipping = false;
							objects.addChild( tempName );
							break;
		
						case 'dynCro':
							tempName = new CrossedObject( material, _w, _h );
							tempName.y = hPos;
							tempName.z = -(child.y-250)*4;
							tempName.x = (child.x-250)*4;
							tempName.useClipping = false;
							objects.addChild( tempName );
							dynamic3DObjList.push({obj3d:tempName , clip:child});
							break;
							
						case 'staWal':
							trace("SEGMENTES :"+child+" : "+_segmentsW+": U "+material.maxU+":  V "+material.maxV);
							tempName = new Plane( material, (30*child.scaleY*13.3),_h ,Number(_segmentsW), Number(_segmentsH));
							tempName.y = hPos;
							tempName.z = -(child.y-250)*4;
							tempName.x = (child.x-250)*4;
							tempName.rotationY = child.rotation + 90;
							tempName.useClipping = false;
							objects.addChild( tempName );
							break;
						
						case 'dynWal':
							tempName = new Plane( material, ( 30 * child.scaleY * 13.3 ),_h ,_segmentsW, _segmentsH);
							tempName.y = hPos;
							tempName.z = -(child.y-250)*4;
							tempName.x = (child.x-250)*4;
							tempName.rotationY = child.rotation + 90;
							tempName.useClipping = false;
							objects.addChild( tempName );
							dynamic3DObjList.push({obj3d:tempName , clip:child});
							break;
						
						case 'staBox':
							tempName = new BoxObject( material, (30*child.scaleY*13.3),(30*child.scaleX*13.3),_h)
							tempName.y = hPos;
							tempName.z = -(child.y-250)*4;
							tempName.x = (child.x-250)*4;
							tempName.rotationY = child.rotation + 90;
							tempName.useClipping = false;
							objects.addChild( tempName );
							break;
							
						case 'dynBox':
							tempName = new BoxObject( material, ( 30 * child.scaleY * 13.3 ),( 30 * child.scaleX * 13.3 ),_h )
							tempName.y = hPos;
							tempName.z = -(child.y-250)*4;
							tempName.x = (child.x-250)*4;
							tempName.rotationY = child.rotation + 90;
							tempName.useClipping = false;
							objects.addChild( tempName );
							dynamic3DObjList.push({obj3d:tempName , clip:child});
							break;
							
						case 'staBal':
							tempName = new Sphere( material, ( 30 * child.scaleY * 13.3 ) / 2 , 16, 16 );
							tempName.y = hPos;
							tempName.z = -(child.y-250)*4;
							tempName.x = (child.x-250)*4;
							tempName.rotationY = child.rotation + 90;
							tempName.useClipping = false;
							objects.addChild( tempName );
							break;
							
						case 'dynBal':
							tempName = new Sphere( material, ( 30 * child.scaleY * 13.3 ) / 2, 16, 16 );
							tempName.y = hPos;
							tempName.z = -(child.y-250)*4;
							tempName.x = (child.x-250)*4;
							//tempName.rotationY = child.rotation + 90;
							tempName.useClipping = false;
							objects.addChild( tempName );
							dynamic3DObjList.push({obj3d:tempName , clip:child});
							break;
							
						case 'dynCyl':
							tempName = new Cylinder( material, ( 30 * child.scaleY * 13.3 ) / 2, ( 30 * child.scaleX * 13.3 ) );
							tempName.y = hPos;
							tempName.z = -(child.y-250)*4;
							tempName.x = (child.x-250)*4;
							tempName.rotationY = child.rotation + 90;
							tempName.useClipping = false;
							objects.addChild( tempName );
							dynamic3DObjList.push({obj3d:tempName , clip:child});
							break;
							
					}
				}
			//viewport.containerSprite.sortMode = ViewportLayerSortMode.INDEX_SORT;
			return dynamic3DObjList;
		}
		
		
        private function init3D():void {  
        	
			startPhysicEngine();
			
			springCamera = new SpringCamera3D(30, 25, 1000, true, true);
			springCamera.mass = 20;
			springCamera.damping = 18;
			springCamera.stiffness = 6;
			springCamera.positionOffset = new Number3D(-15, 4, 20);
			springCamera.lookOffset = new Number3D(0, 1, 0);
			
        	sphere = new Sphere(new WireframeMaterial());
			scene.addChild(sphere);
			
			
			
			// START BUILDING 3D WORLD
			var obj3DList = convertClipTo3DWorld(root["room1"]);
			
			
			startRendering();
			//mt = new Load3DMaterial(_room, _userID1, _userID2);
			//addChild(mt);
			//mt.addEventListener("mapsLoadedEvent",onMapsLoaded);
        }   

		
		override protected function onRenderTick(event:Event = null):void
		{
			sphere.yaw(1);
			renderer.renderScene(scene, springCamera, viewport);
		}
		

		
    }   
}  
